/**
 * Fichier Main.java : Définition de classe fr.unice.gnpt.Main : Point d'entrée
 * de l'application
 * 
 * Auteurs : Groupe GNPT : Gastinel, Nicolas, Pellegrino, Trovato
 * 
 * $Id: Main.java 498 2008-11-12 20:26:04Z Cyprien NICOLAS $
 */
package fr.unice.gnpt;

import javax.swing.SwingUtilities;

import fr.unice.gnpt.core.dao.DaoException;
import fr.unice.gnpt.core.dao.factory.FabriqueDao;
import fr.unice.gnpt.core.init.Initialisation;
import fr.unice.gnpt.core.util.Journal;
import fr.unice.gnpt.gui.Interface;
import fr.unice.gnpt.gui.util.TypeUtilisateur;

/**
 * Classe servant de point d'entrée de l'application.
 * <p>
 * Cette classe initialise plusieurs objets globaux de l'application, et se
 * charge d'instancier les objets, et d'appeler les méthodes nécessaires au
 * démarrage de l'application.
 * <p>
 * <b>Schéma d'initialisation et de lancement de l'application :</b><br>
 * La classe Main va interroger la classe Initialisation. Cette dernière va
 * s'occuper de récupérer les informations nécessaire au lancement de
 * l'application, ou bien les demander au besoin. Ensuite, la classe Main va
 * demander à l'application de démarrer, soit en utilisant Swing, soit en ligne
 * de commande.
 * <p>
 * L'instance créé par la fonction main existe durant toute la durée de vie de
 * l'application, afin de pouvoir accéder aux informations externes à
 * l'interface graphique.
 * 
 * @author gnpt
 * @version 0.1.$LastChangeRevision$
 */
public final class Main {

	/**
	 * Un booléen qui indique si on est en mode graphique. Pas d'utilité dans
	 * l'application, mais ça aide à réfléchir à la structure.
	 */
	private static boolean modeGraphique = true;
	/**
	 * Une référence vers l'interface graphique.
	 */
	private static Interface gui = null;
	/**
	 * L'enregistreur d'événement de l'application.
	 */
	private static Journal journal = null;
	/**
	 * Le type d'utilisateur de l'application (Enseignement ou Coordonateur)
	 */
	private static TypeUtilisateur typeUtilisateur = null;

	/**
	 * Point d'entré de l'application
	 * 
	 * @param args
	 *            les arguments de la ligne de commande
	 */
	public static void main(String[] args) {
		if (args.length > 0 && args[0].equals("-nw")) {
			// On ne lance pas l'interface graphique
			Main.modeGraphique = false;
		}

		// FIXME Indique d'écrire le journal sur sysout
		Journal.setPrintToSysout(true);
		Main.journal = Journal.getJournal();
		Main.gui = new Interface();

		final Initialisation init = Initialisation.newInstance();
		journal.logInfo("Démarrage de l'initialisation");
		init.startInitialisation();
		if (Main.modeGraphique) {
			journal.logInfo("Création de l'interface graphique");
			SwingUtilities.invokeLater(new Runnable() {
				public void run() {
					Main.getGUI().creerEtAfficher(Main.getTypeUtilisateur());
				}
			});
		} else {
			Main.journal.logErreur("Mode console non implémenté");
			Main.exit(1);
		}
	}

	/**
	 * Accesseur pour le champ privé de la classe Main indiquant si
	 * l'application se lance en mode graphique.
	 * 
	 * @return {@code true} si l'application est en mode graphique (par défaut).
	 */
	public static boolean isModeGraphique() {
		return Main.modeGraphique;
	}

	/**
	 * Accesseur statique pour l'interface graphique
	 * 
	 * @return l'interface graphique associée à l'application.
	 */
	public static Interface getGUI() {
		return Main.gui;
	}

	/**
	 * Accesseur statique pour le système de journalisation.
	 * 
	 * @return l'instance de Journal liée à l'application
	 */
	public static Journal getJournal() {
		return Main.journal;
	}

	/**
	 * Renvoie le type d'utilisateur de l'application.
	 * 
	 * @return <code>COORDONNATEUR</code> ou <code>ENSEIGNANT</code>.
	 */
	public static TypeUtilisateur getTypeUtilisateur() {
		return typeUtilisateur;
	}

	/**
	 * Affecte le type d'utilisateur de l'application.
	 * 
	 * @param utilisateur
	 *            donnée de la fenêtre de configuration.
	 */
	public static void setTypeUtilisateur(int utilisateur) {
		switch (utilisateur) {
		case 0:
			Main.typeUtilisateur = TypeUtilisateur.ENSEIGNANT;
			break;
		case 1:
			Main.typeUtilisateur = TypeUtilisateur.COORDONNATEUR;
			break;
		}
	}

	/**
	 * Méthode statique de sortie de l'application. Cette méthode s'occupe de
	 * libérer les ressources et appelle System.exit(status).
	 * 
	 * @param status
	 *            le code de sortie de l'application
	 */
	public static void exit(int status) {
		try {
			FabriqueDao fab = FabriqueDao.getFabriqueDao();
			if (fab != null) fab.getDaoCours().getConnexion().dispose();
		} catch (DaoException e) {
			Main.journal.logErreur("Exception lors de dispose()");
		}
		if (status > 0) {
			Main.journal.logErreur("Sortie de l'application avec code "
					+ status);
		} else {
			Main.journal.logInfo("Sortie de l'application.");
		}
		Main.journal.terminer();
		System.exit(status);
	}

}
